package com.tau.egonetwork.gui.core;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;

import com.tau.egonetwork.common.Log;
import com.tau.egonetwork.gui.Environment;

public abstract class BasicDialog extends Dialog {

	protected Shell shell;
	
	protected abstract void createWindowContents();
	protected abstract Object setReturnValue();
	protected abstract void onOKClicked();
	
	private Button okButton;
	
	private boolean openDialog = true;
	private boolean initialEnabledOKButton = true;

	public BasicDialog(Shell parent) {
		super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
	}
	
	public final Object open() {
		
		Log.writeLineToLog("Dialog's open() called for '" + getText() + "'");
		
		shell = new Shell(getParent(), getStyle());
		shell.setText(getText());
		
		Log.writeLineToLog("createBaseWindowContents()");

		createBaseWindowContents();
		
		if (openDialog) {
			
			shell.pack();
			
			//set shell at the center of display:
		    Monitor primary = getParent().getMonitor();
		    Rectangle bounds = primary.getBounds();
		    Rectangle rect = shell.getBounds();
		    int x = bounds.x + (bounds.width - rect.width) / 2;
		    int y = bounds.y + (bounds.height - rect.height) / 2;
		    shell.setLocation(x, y);
			
			Log.writeLineToLog("opening dialog");

			shell.open();
			
			//keep shell open, waiting for user input:
			Display display = getParent().getDisplay();
			while (!shell.isDisposed()) {
				if (!display.readAndDispatch())
					display.sleep();
			}
		}
		
		return setReturnValue();
		
	}
	
	protected void setDoNotOpenDialog() {
		openDialog = false;
	}
	
	protected void setOKButtonEnabled(boolean enabled) {
		if (okButton == null) {
			initialEnabledOKButton = enabled;
		} else {			
			okButton.setEnabled(enabled);
		}
	}

	private void createBaseWindowContents() {
		
		shell.setLayout(new GridLayout(1, true));
		shell.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		createWindowContents();
		if (!openDialog)
			return;
		
		Composite separatorComposite = new Composite(shell, SWT.NONE);
		GridLayout separatorCompositeGridLayout = new GridLayout(1, true);
		separatorCompositeGridLayout.marginWidth = 0;
		separatorCompositeGridLayout.marginLeft = 0;
		separatorCompositeGridLayout.marginRight = 0;
		separatorComposite.setLayout(separatorCompositeGridLayout);
		separatorComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		
		Label separator = new Label(separatorComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
		GridData separatorGridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
		separatorGridData.horizontalSpan = 2;
		separator.setLayoutData(separatorGridData);
		
		Composite buttonsComposite = new Composite(shell, SWT.NONE);
		GridLayout buttonsCompositeGridLayout = new GridLayout(3, false);
		buttonsCompositeGridLayout.marginWidth = 0;
		buttonsCompositeGridLayout.marginRight = 0;
		buttonsComposite.setLayout(buttonsCompositeGridLayout);
		buttonsComposite.setLayoutData(new GridData(SWT.RIGHT, SWT. CENTER, false, false));
		
		okButton = new Button(buttonsComposite, SWT.PUSH | SWT.FLAT);
		okButton.setText(" OK ");
		okButton.setImage(Environment.ICON_OK);
		okButton.setEnabled(initialEnabledOKButton);
		okButton.addListener(SWT.Selection, new Listener() {
			
			@Override
			public void handleEvent(Event event) {
				Log.writeLineToLog("dialog ok button clicked");
				onOKClicked();
			}
		});
		
		Button cancelButton = new Button(buttonsComposite, SWT.PUSH | SWT.FLAT);
		cancelButton.setText(" Cancel ");
		cancelButton.setImage(Environment.ICON_ERROR);
		cancelButton.addListener(SWT.Selection, new Listener() {
			
			@Override
			public void handleEvent(Event event) {
				Log.writeLineToLog("dialog cancel button clicked");
				shell.close();
			}
		});
		
	}
	
	
}
